﻿// //委托
// //作用
// //1.实现方法的回调机制，使得方法可以作为参数传递
// //2.支持事件模式，是事件背后的基础
// //3.可以动态组合方法链，便于实现多路广播

// //第三步：创建实例化委托
// SimpleDelegate del1 = new SimpleDelegate(SayHello);
// SimpleDelegate del2 = SayHello;

// //二、调用委托
// //1.直接调用
// del1();
// //2.使用Invoke方法
// del1.Invoke();
// //3.带参数调用
// int Subtaract(int x, int y) => x-y;
// CalculateDelegate calc = Add;
// Console.WriteLine(calc(10,5));
// calc = Subtaract;
// Console.WriteLine(calc(10,5));

// //第二步：创建匹配签名的方法
// void SayHello(){
//     Console.WriteLine("Hello,World!");
// }
// int Add(int x, int y) => x+y;


// //第一步：声明委托类型
// //声明一个无返回值、无参数的委托类型
// public delegate void SimpleDelegate();
// //声明一个有返回值、有参数的委托类型
// public delegate int CalculateDelegate(int a, int b);

// //创建委托步骤实例：
// //1.声明委托类型
// //2.创建匹配签名的方法
// //3.实例化委托





// //多播委托
// //委托可以组合多个方法
// //使用 += 添加方法，使用 -= 移除方法
// //按照添加顺序依次执行

// //3.实例化
// ProgressDelegate progressHandler = ShowProgress;
// progressHandler += LogProgress;
// progressHandler(50);

// progressHandler -= LogProgress;
// progressHandler(50);

// //2.匹配签名
// void ShowProgress(int percent){
//     Console.WriteLine($"当前进度：{percent}%");
// }
// void LogProgress(int percent){
//     Console.WriteLine($"文件：{percent}个");
// }




// // //1.声明委托类型
// // public delegate void ProgressDelegate(int percent);

// //内置无返回值委托
// Action<string> print = msg => Console.WriteLine(msg);
// //内置有返回值委托
// Func<int, int, int> multiply = (x, y) => x*y;
// //返回bool的委托
// Predicate<int> isEven = num => num%2 == 0; 





//事件
//基于委托的封装，是特殊的委托类型成员
//实现观察者模式(发布-订阅模型)
//事件它用于在对象状态发生变化时通知其他对象

//基本语法声明：
//public event 委托类型 事件名称：
public delegate void MessageHandler(string msg);
/// <summary>
/// 发布者类，负责定义和出发消息接收事件
/// </summary>

class Publisher1{
    public event MessageHandler OnMessageReceived;

    /// <summary>
    /// 模拟发送消息方法：触发OnMessageReceived事件
    /// </summary>
    /// <param name="content">要发送的消息内容 </param>
    public void SendMessage(string content){
        OnMessageReceived?.Invoke(content);
    }
}

class Programe {
    static void main(){
        //创建发布者实例
        Publisher1 publisher1 = new Publisher1();
        //订阅事件
        publisher1.OnMessageReceived += ShowInConsole;
        //调用发布者的方法，触发事件并传递消息内容
        publisher1.SendMessage("系统启动");
        //如果publisher1的生命周期长于订阅它的对象，而忘记在不需要的时候取消调用
        //委托链仍然持有对目标方法的引用，可能导致这些对象无法被垃圾回收，造成内存泄漏
        //在合适的位置 -= 取消订阅
        publisher1.OnMessageReceived -= ShowInConsole;
    }

    /// <summary>
    /// 事件处理方法：在控制台显示接收到的消息
    /// </summary>
    /// <param name="msg">接收到的消息内容 </param>
    static void ShowInConsole(string msg){
        Console.WriteLine($"控制台显示：{msg}");
    }
}